#include<page_manager.h>
#include<config.h>
#include<disp_manager.h>
#include <math.h>
#include<ui.h>
#include <stdlib.h>


#define X_GAP 5
#define Y_GAP 5

static Button g_tButtonsBuf[ITEMCFG_MAX_NUM];
static int g_ButtonCount = 0;

static int MainPageOnPressed(PButton ptButton, PDispBuffer ptDispBuffer, PInputEvent ptInputEvent)
{
	unsigned int dwColor = BUTTON_DEFAULT_COLOR;
	char name[100];
	char status[100];
	char* StrButton;
	char* command_status[3] = {"err", "ok", "percent"};
	int command_status_index = 0;
	PItemCfg ptItemCfg;
	char command[1000];
	//printf("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);

	StrButton = ptButton->name;
	//printf("%s\n",StrButton);

	/* 1.对于触摸屏事件 */
	if((ptInputEvent->iType == INPUT_TYPE_TOUCH) && (ptInputEvent->iPressure ))
	{
		/* 1.1 分辨能否被点击 */
		if (GetItemCfgByName(ptButton->name)->bCanBeTouched == 0)
			return -1;

		/* 1.2 修改颜色 */
		ptButton->status = !ptButton->status;
		if(ptButton->status)
		{
			dwColor = BUTTON_PRESSED_COLOR;
			command_status_index = 1;
		}	
	}

	/* 2.对于网络事件 */
	else if(ptInputEvent->iType == INPUT_TYPE_NET)
	{
		sscanf(ptInputEvent->str,"%s %s", name, status);
		if(strcmp("ok", status) == 0)
		{
			dwColor = BUTTON_PRESSED_COLOR;
			command_status_index = 1;
		}
		else if(strcmp("err",status) == 0)
		{
			dwColor = BUTTON_DEFAULT_COLOR;
			command_status_index = 0;
		}
		else if(status[0] <= '9' && status[0] >= '0')
		{
			dwColor = BUTTON_PERSENT_COLOR;
			command_status_index = 2;
			StrButton = status;
		}
		else
		{
			return -1;
		}
		
	}
	else
	{
		return -1;
	}
	
	DrawRegion(&ptButton->tRegion, dwColor);
	
	DrawTextInRegionCenter(StrButton, &ptButton->tRegion, BUTTON_TEXT_COLOR);

	FlushDisplayRegion(&ptButton->tRegion, ptDispBuffer);

	
	/* 执行command */
	ptItemCfg = GetItemCfgByName(ptButton->name);
	if(ptItemCfg->command[0] != '\0')
	{
		sprintf(command, "%s %s", ptItemCfg->command, command_status[command_status_index]);
		system(command);
	}
	return 0;

}

static int GetFontSizeForAllButton(void)
{
	int i;
	int max_strlenth = 0;
	int strlenth;
	int index = 0;
	RegionCartesian tRegionCar;
	float kx, ky,k;
	int fontsize;

	/* 找出name最长的Button */
	for(i = 0; i < g_ButtonCount; i++)
	{
		strlenth = strlen(g_tButtonsBuf[i].name);
		if(max_strlenth < strlenth)
		{
			max_strlenth = strlenth;
			index = i;
		}
	}

	/* 以font_size = 100, 算出它的外框 */
	SetFontSize(100);
	GetStringRegionCar(g_tButtonsBuf[index].name, &tRegionCar);
	
	kx = (float)g_tButtonsBuf[index].tRegion.iWidth / tRegionCar.iWidth;
	ky = (float)g_tButtonsBuf[index].tRegion.iHeight / tRegionCar.iHeight;
	
	if (kx < ky)
		k = kx;
	else
		k = ky;

	/* 反算出font size, 只取0.80, 避免文字过于接近边界 */
	fontsize = k * 100 * 0.8;
	
	/*字体很小
	ky = g_tButtonsBuf[index].tRegion.iHeight / tRegionCar.iHeight;
	kx = g_tButtonsBuf[index].tRegion.iWidth / tRegionCar.iWidth;
	
	
	fontsize = ( tRegionCar.iWidth / max_strlenth ) * kx; 
	if(fontsize > tRegionCar.iHeight * ky)
		fontsize = tRegionCar.iHeight * ky;
	*/
	return fontsize;
}
static void GenerateButtons(void)
{	
	int n;
	PDispBuffer ptDispBuffer;
	int xres,yres;
	int button_width,button_height;
	int n_per_line;
	int start_x, start_y;
	int row;
	int i, j;
	PButton ptButton;
	int index = 0;
	int fontsize;
		
	g_ButtonCount = n = GetItemCfgCount();
	
	ptDispBuffer = GetDisplayBuffer();

	xres = ptDispBuffer->iXres;
	yres = ptDispBuffer->iYres;

	//claculate the size of each button 
	button_width = sqrt(xres * yres * (1.0 / 0.618 ) / n);
	n_per_line = xres / button_width + 1; // +1 avoid overstep the boundary
	button_width = xres / n_per_line;//反算出width,使width更小一点
	button_height = button_width * 0.618;

	row = n / n_per_line;
	if( row * n_per_line < n)
		row++;
	
	start_x = (xres - button_width * n_per_line) / 2;
	start_y = (yres - button_height * row) / 2;

	
	//Init each button
	for(i = 0; (i < row) && (index < n); i++)
	{
		for(j = 0; (j < n_per_line) && (index < n); j++)
		{
			ptButton = &g_tButtonsBuf[index];
			ptButton->tRegion.iLeftUpX = start_x + button_width * j;
			ptButton->tRegion.iLeftUpY = start_y + button_height * i;
			ptButton->tRegion.iHeight = button_height - X_GAP;
			ptButton->tRegion.iWidth = button_width - Y_GAP;
		
			InitButton(ptButton, GetItemCfgByIndex(index)->name, NULL, NULL, MainPageOnPressed);
			index++;	
		}
	}

	fontsize = GetFontSizeForAllButton();

	for(index = 0; index < n; index++)
	{
		g_tButtonsBuf[index].fontsize = fontsize;
		g_tButtonsBuf[index].OnDraw(&g_tButtonsBuf[index], ptDispBuffer);
		//printf("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);
	}
	
}

static int isTouchPointInRegion(int X, int Y, PRegion ptRegion)
{
	if (X < ptRegion->iLeftUpX || X >= ptRegion->iLeftUpX + ptRegion->iWidth)
		return 0;

	if (Y < ptRegion->iLeftUpY || Y >= ptRegion->iLeftUpY + ptRegion->iHeight)
		return 0;

	return 1;
}

static PButton GetButtonByName(char *name)
{
	int i;

	for (i = 0; i < g_ButtonCount; i++)
	{
		if (strcmp(name, g_tButtonsBuf[i].name) == 0)
			return &g_tButtonsBuf[i];
	}

	return NULL;
}


static PButton GetButtonByInputEvent(PInputEvent ptInputEvent)
{
	int i;
	char name[100];
	
	if (ptInputEvent->iType == INPUT_TYPE_TOUCH)
	{
		for (i = 0; i < g_ButtonCount; i++)
		{
			if (isTouchPointInRegion(ptInputEvent->iX, ptInputEvent->iY, &g_tButtonsBuf[i].tRegion))
				return &g_tButtonsBuf[i];
		}
	}
	else if (ptInputEvent->iType == INPUT_TYPE_NET)
	{
		sscanf(ptInputEvent->str, "%[^ ]", name);
		return GetButtonByName(name);
	}
	else
	{
		return NULL;
	}
	return NULL;
}


//param 参数
static void MainPageRun(void *pParams)
{
	PButton ptButton;
	InputEvent tInputEvent;
	PDispBuffer ptDispBuf = GetDisplayBuffer();
	int error;
	//printf("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);


	/* 解析配置文件 */
	ParseConfigFile();
	
	
	/* 根据配置文件生成按钮、界面 */
	GenerateButtons();
	//printf("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);

	while (1)
	{
		/* 读取输入事件 */
		error = GetInputEvent(&tInputEvent);
		if (error)
			continue;

		/* 根据输入事件找到按钮 */
		ptButton = GetButtonByInputEvent(&tInputEvent);
		if (!ptButton)
			continue;
			
	
		/* 调用按钮的OnPressed函数 */
		ptButton->OnPressed(ptButton, ptDispBuf, &tInputEvent);
	}
	
}

static PageAction g_tMainPageAction = {
	.name = "main",
	.Run  = MainPageRun,
};


void MainPageRegister(void)
{
	RegisterPageAction(&g_tMainPageAction);
}
